#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QGridLayout>
#include <QPixmap>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QDir>
#include <QMessageBox>
#include <QSqlError>
#include <QNetworkProxy>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <QGuiApplication>
#include <QScreen>
#include <QRandomGenerator>
#include <QString>

//简单延时函数
void delay_ms(uint32_t ms)
{
    uint32_t i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 8000; j++);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    initTcpConnection();
    initDatabase();
    setupUI();

    // 建立接收信号槽连接
    connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::readServerMessage);

    //打开串口文件
    if(!initSerialPort("/dev/ttyUSB1")){
        qDebug() << "fail to open serial port" ;
        qDebug() << strerror(errno);
    }
}

//消息弹窗居中显示
void MainWindow::showCenteredMessageBox(const QString &title, const QString &text)
{
    QMessageBox *box = new QMessageBox(QMessageBox::Warning, title, text, QMessageBox::Ok, this);
    box->setWindowModality(Qt::ApplicationModal);
    box->setAttribute(Qt::WA_DeleteOnClose);

    QRect parentRect = this->geometry();
    QSize boxSize = box->sizeHint();
    int x = parentRect.x() + (parentRect.width() - boxSize.width()) / 2;
    int y = parentRect.y() + (parentRect.height() - boxSize.height()) / 2;
    box->move(x, y);

    box->show();
}


//计算空柜
//QList<int> getUnusedLockerIndices(const sendRig &msg)
//{
//    QList<int> freeIndices;
//    for (int i = 0; i < 10; i++) {
//        if (msg.num[i] == 0) {
//            freeIndices << i;
//        }
//    }
//    return freeIndices;
//}

//后台服务器自动连接
void MainWindow::initTcpConnection()
{
    tcpSocket = new QTcpSocket(this);
    tcpSocket->setProxy(QNetworkProxy::NoProxy);
    tcpSocket->connectToHost("192.168.6.237", 6666);

    if (!tcpSocket->waitForConnected(3000)) {
        QMessageBox::critical(this, "错误", "连接服务器失败！");
//        showCenteredMessageBox("错误","连接服务器失败！");
    } else {
        qDebug() << "已连接服务器";
    }
}

//后台连接数据库创建表
void MainWindow::initDatabase()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("express.db");
    if (!db.open()) {
        qDebug() << "数据库打开失败";
        return;
    }

    QSqlQuery query;
    query.exec("CREATE TABLE IF NOT EXISTS order1 ("
               "name TEXT, order_id TEXT, courier_phone TEXT, "
               "receiver_phone TEXT, area_code INT, identity_code TEXT)");
}

//UI界面设置
void MainWindow::setupUI()
{
//    QScreen *screen = QGuiApplication::primaryScreen();
//        if (screen) {
//            QRect screenGeometry = screen->geometry();
//            int screenWidth = screenGeometry.width();
//            int screenHeight = screenGeometry.height();
//            qDebug() << "Screen size:" << screenWidth << "x" << screenHeight;
//            qDebug() << "Platform plugin:" << QGuiApplication::platformName();


//            this->setGeometry(0, 0, screenWidth, screenHeight);  // 设置窗口为全屏大小
//            // 或者 setFixedSize(screenWidth, screenHeight);
//        } else {
//            qDebug() << "Failed to get screen.";
//        }

    this->setFixedSize(850, 480);
    stackedWidget = new QStackedWidget(this);
    setCentralWidget(stackedWidget);

    inactivityTimer = new QTimer(this);
    connect(inactivityTimer, &QTimer::timeout, this, &MainWindow::updateCountdown);

    // 主界面
    mainPage = new QWidget(this);
    QHBoxLayout *mainLayout = new QHBoxLayout(mainPage);

    adLabel = new QLabel(mainPage);
    adLabel->setFixedSize(530, 480);
    adLabel->setScaledContents(true);
    mainLayout->addWidget(adLabel);

    adImages << ":/pic/fuwo.jpg" << ":/pic/fuwo2.jpg" << ":/pic/nongchang.jpg" << ":/pic/nongchang2.jpg" << ":/pic/dapeng.jpg";
    adTimer = new QTimer(this);
    connect(adTimer, &QTimer::timeout, this, &MainWindow::nextAdImage);
    adTimer->start(3000);
    nextAdImage();

    QVBoxLayout *btnLayout = new QVBoxLayout;
    QPushButton *depositBtn = new QPushButton("存件");
    depositBtn->setStyleSheet("background-color: rgb(115, 210, 22);font: 56pt ;");
    QPushButton *retrieveBtn = new QPushButton("取件");
    retrieveBtn->setStyleSheet("background-color: rgb(239, 41, 41);font: 56pt ;");
    depositBtn->setFixedHeight(120);
    retrieveBtn->setFixedHeight(120);
    btnLayout->addWidget(depositBtn);
    btnLayout->addWidget(retrieveBtn);
    mainLayout->addLayout(btnLayout);

    // 存件页面
    depositPage = new QWidget(this);
    QHBoxLayout *depMainLayout = new QHBoxLayout(depositPage);

    // 左侧区域（占 2/3）
    QVBoxLayout *leftLayout = new QVBoxLayout;
    QLabel *areaLabel = new QLabel("区域码：0001", depositPage);
    areaLabel->setAlignment(Qt::AlignCenter);
    areaLabel->setStyleSheet("font-size: 32px;");
    leftLayout->addStretch();
    leftLayout->addWidget(areaLabel, 0, Qt::AlignCenter);
    leftLayout->addStretch();
    depMainLayout->addLayout(leftLayout, 2); // 占比 2/3

    // 右侧区域（占 1/3）
    QVBoxLayout *rightLayout = new QVBoxLayout;
    depositBackBtn = new QPushButton("返回(10)");
    depositBackBtn->setFixedSize(200, 100);
    rightLayout->addStretch();
    rightLayout->addWidget(depositBackBtn, 0, Qt::AlignHCenter | Qt::AlignVCenter);
    rightLayout->addStretch();
    depMainLayout->addLayout(rightLayout, 1); // 占比 1/3


    connect(depositBtn, &QPushButton::clicked, this, &MainWindow::showDepositPage);
    connect(depositBackBtn, &QPushButton::clicked, this, &MainWindow::showMainPage);

    // 取件页面布局（紧凑九宫格）
    retrievePage = new QWidget(this);
    QHBoxLayout *retLayout = new QHBoxLayout(retrievePage);
    retLayout->setContentsMargins(20, 20, 20, 20);  // 外围留边距

    // 左侧区域（九宫格 + 输入框）
    QVBoxLayout *numLayout = new QVBoxLayout;
    numLayout->setAlignment(Qt::AlignCenter);

    // LineEdit
    codeEdit = new QLineEdit;
    codeEdit->setFixedSize(260, 40);
    codeEdit->setAlignment(Qt::AlignCenter);
    codeEdit->setReadOnly(true);
    numLayout->addWidget(codeEdit);
    numLayout->addSpacing(10);

    // 紧凑九宫格按钮布局
    QGridLayout *grid = new QGridLayout;
    grid->setSpacing(0);  // 按钮之间无间隙
    QStringList keys = {
        "1", "2", "3",
        "4", "5", "6",
        "7", "8", "9",
        "确认", "0", "删除"
    };

    for (int i = 0; i < keys.size(); ++i) {
        QPushButton *btn = new QPushButton(keys[i]);
        btn->setFixedSize(87, 60);  // 总宽260 = 87*3 - 1 间隙
        btn->setStyleSheet("margin: 0px; padding: 0px;");
        int row = i / 3;
        int col = i % 3;
        grid->addWidget(btn, row, col);

        if (keys[i] == "确认") {
            connect(btn, &QPushButton::clicked, this, &MainWindow::confirmClicked);
        } else if (keys[i] == "删除") {
            connect(btn, &QPushButton::clicked, this, &MainWindow::deleteClicked);
        } else {
            connect(btn, &QPushButton::clicked, this, &MainWindow::numberClicked);
        }
    }

    numLayout->addLayout(grid);
    retLayout->addLayout(numLayout, 2);  // 左边2/3区域

    // 右侧区域（返回按钮）
    QVBoxLayout *retBtnLayout = new QVBoxLayout;
    retrieveBackBtn = new QPushButton("返回(10)");
    retrieveBackBtn->setFixedSize(200, 100);
    retBtnLayout->addStretch();
    retBtnLayout->addWidget(retrieveBackBtn, 0, Qt::AlignCenter);
    retBtnLayout->addStretch();
    retLayout->addLayout(retBtnLayout, 1);  // 右边1/3区域


    connect(retrieveBtn, &QPushButton::clicked, this, &MainWindow::showRetrievePage);
    connect(retrieveBackBtn, &QPushButton::clicked, this, &MainWindow::showMainPage);

    stackedWidget->addWidget(mainPage);
    stackedWidget->addWidget(depositPage);
    stackedWidget->addWidget(retrievePage);
}

//UI界面广告图片循环播放设置
void MainWindow::nextAdImage()
{
    if (adImages.isEmpty()) return;
    adLabel->setPixmap(QPixmap(adImages[adIndex]));
    adIndex = (adIndex + 1) % adImages.size();
}

//跳转存件页面，无按钮点击事件自动返回主页面设置
void MainWindow::showDepositPage()
{
    stackedWidget->setCurrentWidget(depositPage);
    countdown = 10;
    depositBackBtn->setText("返回(10)");
    inactivityTimer->start(1000);
}

//跳转取件页面，无按钮点击事件自动返回主页面设置
void MainWindow::showRetrievePage()
{
    stackedWidget->setCurrentWidget(retrievePage);
    countdown = 10;
    retrieveBackBtn->setText("返回(10)");
    codeEdit->clear();
    inactivityTimer->start(1000);
}

//跳转回主页面
void MainWindow::showMainPage()
{
    inactivityTimer->stop();
    stackedWidget->setCurrentWidget(mainPage);
    codeEdit->clear();
}

//返回倒计时设置
void MainWindow::updateCountdown()
{
    countdown--;
    if (stackedWidget->currentWidget() == depositPage)
        depositBackBtn->setText(QString("返回(%1)").arg(countdown));
    else if (stackedWidget->currentWidget() == retrievePage)
        retrieveBackBtn->setText(QString("返回(%1)").arg(countdown));

    if (countdown == 0)
        showMainPage();
}

//按键输入信息，重置返回倒计时
void MainWindow::numberClicked()
{
    QPushButton *btn = qobject_cast<QPushButton *>(sender());
    if (btn) codeEdit->insert(btn->text());
    countdown = 10;
}

//"删除键"功能
void MainWindow::deleteClicked()
{
    codeEdit->backspace();
    countdown = 10;
}

//"确认键"功能，发送消息给服务器
void MainWindow::confirmClicked()
{
    QString code = codeEdit->text();
    sendRig msg;

    if(code.isEmpty()){
        QMessageBox::warning(this,"注意","请输入取件码");
//        showCenteredMessageBox("注意","请输入取件码");
        return;
    }
    qDebug()<<"1111111111111";
    QSqlQuery query;
    query.prepare("SELECT * FROM order1 WHERE identity_code = :code");
    query.bindValue(":code", code);
    if(!query.exec()){
        qDebug() << "查询数据失败：1" << query.lastError().text();
    }else {
        qDebug() << "查询数据成功2";
    }

    if(query.next()){
        qDebug() << "匹配到对应订单信息3";
        //开柜
//        sendRig msg;
        switch (msg.IC) {
        case 0:
            sendCommand("1");
            delay_ms(300);
            sendCommand("0");
            break;
        case 1:
            sendCommand("1");
            delay_ms(300);
            sendCommand("0");
        case 2:
            sendCommand("1");
            delay_ms(300);
            sendCommand("0");
        case 3:
            sendCommand("1");
            delay_ms(300);
            sendCommand("0");
        case 4:
            sendCommand("1");
            delay_ms(300);
            sendCommand("0");
        default:
            break;
        }
        qDebug()<<"22222222222222";
        //将订单信息发送给服务器
        memset(&msg,0,sizeof (msg));
        msg.type = 9;
        QString name = query.value("name").toString();
        QString order_id = query.value("order_id").toString();
        QString courier_phone = query.value("courier_phone").toString();
        QString receiver_phone = query.value("receiver_phone").toString();
        QString area_code = query.value("area_code").toString();
        QString identity_code = query.value("identity_code").toString();

        strncpy(msg.Account,name.toUtf8().constData(),sizeof (msg.Account)-1);
        strncpy(msg.ID,order_id.toUtf8().constData(),sizeof (msg.ID)-1);
        strncpy(msg.tele,courier_phone.toUtf8().constData(),sizeof (msg.tele)-1);
        strncpy(msg.telewo,receiver_phone.toUtf8().constData(),sizeof (msg.telewo)-1);
        strncpy(msg.password,identity_code.toUtf8().constData(),sizeof (msg.password)-1);
        msg.IC = area_code.toInt();

        if(tcpSocket && tcpSocket->isOpen()){
            tcpSocket->write(reinterpret_cast<const char *>(&msg),sizeof (sendRig));
            tcpSocket->flush();
            qDebug() << "已将结构体中的数据发送给服务器4";
        }else {
//            QMessageBox::warning(this,"警告","发送数据失败");
            showCenteredMessageBox("警告","发送数据失败");
        }
        //删除数据库中录入的该订单信息
        QSqlQuery deletequery;
        deletequery.prepare("DELETE FROM order1 WHERE identity_code = :code");
        deletequery.bindValue(":code", code);

        if(!deletequery.exec()){
            qDebug() << "删除失败5" << deletequery.lastError().text();
        }else {
            qDebug() << "删除成功6";
        }
    }else {
        qDebug() << "未匹配到对应订单7";
        QMessageBox::warning(this,"失败","无效取件码");
    }
    qDebug()<<"9999999999";
    countdown = 10;
}

//计算空柜
//QList<int> getUnusedLockerIndices(const sendRig &msg)
//{
//    QList<int> freeIndices;
//    for (int i = 0; i < 10; i++) {
//        if (msg.num[i] == 0) {
//            freeIndices << i;
//        }
//    }
//    return freeIndices;
//}

//接收服务器发送的数据
//void MainWindow::readServerMessage()
//{
//    qDebug()<<"*****************";
//    while (tcpSocket->bytesAvailable() >= sizeof(sendRig)) {
//            sendRig msg;
//            tcpSocket->read(reinterpret_cast<char*>(&msg), sizeof(sendRig));

//            switch (msg.type) {
//            case 5:
//            {
//                QList<int> freeIndices = getUnusedLockerIndices(msg);

//                if (freeIndices.isEmpty()) {
//                    qDebug() << "没有空闲柜子";
//                } else {
//                    qDebug() << "空闲柜子编号：" << freeIndices;
//                }

//                // 修改结构体为响应消息
//                msg.type = 6;

//                // 将 num 数组全置1，在设置空闲柜标志位为 0（表示这些柜子空闲）
//                for (int i = 0; i < 10; i++) {
//                    msg.num[i] = 1;
//                }
//                for (int index : freeIndices) {
//                    msg.num[index] = 0;
//                }

//                for (int x=0;x<10;x++) {
//                    qDebug() << msg.num[x];
//                }

//                // 回传给服务器
//                if (tcpSocket->isOpen()) {
//                    tcpSocket->write(reinterpret_cast<char*>(&msg), sizeof(sendRig));
//                    qDebug() << "已将空柜信息发送回服务器，type=6";
//                } else {
//                    qDebug() << "无法发送消息：socket 未连接";
//                }
//            }
//                break;
//            case 7:
//            {
//                //开柜
//                switch (msg.IC) {
//                case 1:
//                    sendCommand("1");
//                    delay_ms(300);
//                    sendCommand("0");
//                    break;
//        //        case 2:
//        //            sendCommand("0");
//                default:
//                    break;
//                }
//                //将服务器发送过来的订单信息存入数据库
//                QSqlQuery query;
//                query.prepare("INSERT INTO order1 (name, order_id, courier_phone, receiver_phone, area_code, identity_code) VALUES "
//                           "(:name, :order_id, :courier_phone, :receiver_phone, :area_code, :identity_code)");
//                query.bindValue(":name",msg.Account);
//                query.bindValue(":order_id",msg.ID);
//                query.bindValue(":courier_phone",msg.tele);
//                query.bindValue(":receiver_phone",msg.telewo);
//                query.bindValue(":area_code",msg.IC);
//                query.bindValue(":identity_code",msg.password);

//                if(!query.exec()){
//                    qDebug() << "插入数据失败:" << query.lastError().text();
//                }else {
//                    qDebug() << "插入数据成功";
//                }

//                msg.type = 8;

//                if(tcpSocket->isOpen()){
//                    tcpSocket->write(reinterpret_cast<char *>(&msg),sizeof (sendRig));
//                    qDebug() << "已将订单信息录入客户端数据库,回传状态至服务器, type=8";
//                }else {
//                    qDebug() << "无法发送消息：socket 未连接";
//                }
//            }
//                break;

//            default:
//                qDebug() << "未知类型：" << msg.type;
//                break;
//            }
//        }
//}

// 获取未使用柜子索引列表（从数据库查询）
QList<int> MainWindow::getUnusedLockerIndicesFromDB()
{
    QList<int> freeIndices;

    // 查询数据库中所有已使用的柜子
    QSqlQuery query;
    query.prepare("SELECT area_code FROM order1 WHERE area_code IS NOT NULL");

    if(!query.exec()) {
        qDebug() << "查询数据库失败:" << query.lastError().text();
        return freeIndices;
    }

    // 收集所有已使用的柜子编号(0-9)
    QSet<int> usedIndices;
    while(query.next()) {
        int usedIndex = query.value("area_code").toInt(); // 直接转换为int
        if(usedIndex >= 0 && usedIndex < 10) { // 确保在有效范围内
            usedIndices.insert(usedIndex);
        }
    }

    // 找出未使用的柜子(0-9)
    for(int i = 0; i < 10; i++) {
        if(!usedIndices.contains(i)) {
            freeIndices.append(i);
        }
    }

    return freeIndices;
}

// 随机分配一个空闲柜子
int MainWindow::assignRandomLocker(const QList<int> &freeIndices)
{
    if(freeIndices.isEmpty()) {
        return -1; // 表示没有空闲柜子
    }

    // 随机选择一个空闲柜子
    int randomIndex = QRandomGenerator::global()->bounded(freeIndices.size());
    return freeIndices.at(randomIndex);
}

//接收服务器发送的数据
void MainWindow::readServerMessage()
{
    qDebug() << "*****************";
    while (tcpSocket->bytesAvailable() >= sizeof(sendRig)) {
        sendRig msg;
        tcpSocket->read(reinterpret_cast<char*>(&msg), sizeof(sendRig));

        switch (msg.type) {
        case 5: // 查询空柜+分配+存储订单
        {
            // 1. 从数据库获取空闲柜子列表
            QList<int> freeIndices;
            QSqlQuery query;
            query.prepare("SELECT area_code FROM order1 WHERE area_code IS NOT NULL");

            if(query.exec()) {
                QSet<int> usedIndices;
                while(query.next()) {
                    int usedIndex = query.value("area_code").toInt();
                    if(usedIndex >= 0 && usedIndex < 10) {
                        usedIndices.insert(usedIndex);
                    }
                }

                // 找出未使用的柜子(0-9)
                for(int i = 0; i < 10; i++) {
                    if(!usedIndices.contains(i)) {
                        freeIndices.append(i);
                    }
                }
            } else {
                qDebug() << "查询数据库失败:" << query.lastError().text();
            }

            // 2. 处理分配逻辑
            if(!freeIndices.isEmpty()) {
                // 随机分配一个空闲柜子
                int assignedLocker = freeIndices.at(QRandomGenerator::global()->bounded(freeIndices.size()));
                msg.IC = assignedLocker; // 记录分配的柜子编号

//                sendCommand("1");
//                delay_ms(200);
//                sendCommand("0");

                qDebug() << "分配柜子：" << assignedLocker << "给订单：" << msg.ID;

                // 3. 存储订单信息到数据库
                QSqlQuery insertQuery;
                insertQuery.prepare("INSERT INTO order1 (name, order_id, courier_phone, "
                                 "receiver_phone, area_code, identity_code) VALUES "
                                 "(:name, :order_id, :courier_phone, :receiver_phone, "
                                 ":area_code, :identity_code)");
                insertQuery.bindValue(":name", msg.Account);
                insertQuery.bindValue(":order_id", msg.ID);
                insertQuery.bindValue(":courier_phone", msg.tele);
                insertQuery.bindValue(":receiver_phone", msg.telewo);
                insertQuery.bindValue(":area_code", msg.IC);
                insertQuery.bindValue(":identity_code", msg.password);

                if(!insertQuery.exec()) {
                    qDebug() << "插入数据失败:" << insertQuery.lastError().text();
/*                    msg.type = 9;*/ // 错误状态
                } else {
                    // 4. 开柜操作
//                    sendCommand(QString::number(msg.IC + 1).toUtf8().constData());
                    sendCommand("1");
                    delay_ms(300);
                    sendCommand("0");

                    // 5. 设置柜子状态数组
                    for(int i = 0; i < 10; i++) {
                        msg.num[i] = (freeIndices.contains(i)) ? 0 : 1;
                    }

                    msg.type = 8; // 成功状态
                    qDebug() << "订单处理完成，分配柜子：" << msg.IC;
                }
            } else {
                qDebug() << "没有可用柜子";
/*                msg.type = 9; */// 错误状态
            }

            // 6. 回传结果给服务器
            if(tcpSocket->isOpen()) {
                tcpSocket->write(reinterpret_cast<char*>(&msg), sizeof(sendRig));
                qDebug() << "已发送处理结果，type=" << msg.type;
            } else {
                qDebug() << "无法发送消息：socket未连接";
            }
        }
        break;

        default:
            qDebug() << "未知消息类型：" << msg.type;
            break;
        }
    }
}

//串口设置
bool MainWindow::initSerialPort(const char *device)
{
    serial_fd = open(device,O_RDWR | O_NOCTTY | O_NDELAY);
    if(serial_fd == -1){
        return false;
    }

    fcntl(serial_fd,F_SETFL,0);

    struct termios options;
    tcgetattr(serial_fd,&options);

    cfsetispeed(&options,B115200);
    cfsetospeed(&options,B115200);

    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CRTSCTS;

    tcsetattr(serial_fd,TCSANOW,&options);
    return true;
}

//控制开锁
void MainWindow::sendCommand(const char *cmd)
{
    if(serial_fd != -1){
        write(serial_fd,cmd,strlen(cmd));
    }
}
